<?php
/*
	Audience testing
*/

function hasAudience($needles, $needle) {
	$needles = explode(",", $needles); // if we have a comma delimited list of needs
	return in_array($needle, $needles) ? true : false;
}

/**
 * This function handles common XSL transformations
 *
 * @param string $xml
 * @param string $xsl
 * @param array $params
 * @return string $content
 **/
function doTransform($xml, $xsl, $params = array()) {
        $xmlObj = new DomDocument();
        $xmlObj->resolveExternals = true;
        if (is_file($xml)) {
                $xmlObj->load($xml);
        } else {
                $xmlObj->loadXML($xml);
        }
        $xslt = new xsltProcessor();
        $xslt->importStyleSheet(DomDocument::load($xsl));
        $xslt->registerPHPFunctions();
	if (!empty($params)) {
		foreach ($params as $paramK=>$paramVal) {
			if (is_array($paramVal)) {
				$xslt->setParameter('',$paramK,implode(",",$paramVal));
 			} else {
				$xslt->setParameter('',$paramK,$paramVal);
			}
		}
	}
        $content = trim($xslt->transformToXML($xmlObj));
        return $content;
}

/**
 * This function returns the title of an XML Resource
 *
 * @param string $cmisId
 * @return string $textNode
 **/
function getDocumentTitle($cmisId) {
        $payload = file_get_contents("http://localhost/ditaserver/?r=cmis/show&path=" . $cmisId . "&raw=1");
        $xml = new SimpleXMLElement($payload);
        $textNode = $xml->xpath('//title[1]/text()');
        $textNode = preg_replace('/.*>(.*)<.*/', '$1', $textNode[0]);
        return $textNode;
}


class CmisController extends Controller
{
	/**
	 * Repository URL
	 */
	public $repo_url ="http://localhost:8080/alfresco/s/cmis";

	/**
	 * Repository Username
	 */
	public $repo_username = "admin";

	/**
	 * Repository Password
	 */
	public $repo_password = "admin";

	/**
	 * Repository Username
	 */
	private $repo_folder = "/";

	/**
	 * Repository debug
	 */
	private $repo_debug = false;

	/**
	 * repo connection
	 */
	static public $client = false;

	public function init() {
		if (!Yii::app()->user->isGuest) {
			 $this->repo_username = Yii::app()->user->name;
			 $this->repo_password = Yii::app()->user->getState("password");
		} else {
			 $this->repo_username = "admin";
			 $this->repo_password = "admin";
		}
		CmisController::$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
	}

	public function actionIndex()
	{
		$this->render('index');
	}

	public static function actionGetCmisId($fileName=false) {
		$topicId = false;
		if (!$fileName) {
			$fileName = $_GET['filename'];
			$topicId = isset($_GET['topicid'])?$_GET['topicid']:false;
		}

        	$fileName = basename($fileName);
        	if (preg_match("/([^\#]*)#(.*)/",$fileName, $regs)) {
                	$fileName = $regs[1];
			$topicId = $regs[2];
        	}
		$query = "SELECT * FROM cmis:document WHERE cmis:name = '" . $fileName . "'";
		$objs = CmisController::$client->query($query);
		$nodes = array();
		foreach ($objs->objectList as $obj) {
			$nodes[] = (string)$obj->properties['cmis:objectId'];
		}
		if (sizeof($nodes) > 1 && $topicId) { //we have more than one result, search for result with ID
			foreach ($nodes as $node) {
				$document = CmisController::$client->getContentStream($node);
        			$xml = new SimpleXMLElement($document);
        			$textNode = $xml->xpath('//*[@id = "' . $topicId . '"]');
				if (!empty($textNode)) {
					$id = $node;
				}
			}
		} elseif(isset($nodes[0])) {
			$id = $nodes[0];
		} else {
			$id = false;
		}
        	return $id; 
	}

	/**
	 * Document is used to fetch URLS from XSL
	 *
	 * @param string $url
	 * @return string $doc
	 **/
	public static function actionGetDocument($id) {
	        if (!empty($id)) {
        		$payload = CmisController::$client->getContentStream($id);
        		$doc = new DOMDocument;
        		$doc->resolveExternals = true;
        		if (!empty($payload)) {
                		$doc->loadXml($payload);
        		} else {
                		$doc->loadXml("<topic><title>" . rawurlencode($url) . "</title><body /></topic>");
        		}
        		return $doc;
        	} else {
                	return "<root />";
        	}
	}



	public function actionSearch() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		$q = str_replace(" ","_",$_GET['q']);
		$query = "SELECT * FROM cmis:document WHERE cmis:name like '%" . $q . "%' or contains('" . $q . "')";
		$objs = $client->query($query);
		foreach ($objs->objectList as $obj) {
			/* cmis:baseTypeId is not set, defaults to else in all cases for internet explorer */
			if (isset($obj->properties['cmis:baseTypeId']) && $obj->properties['cmis:baseTypeId'] == "cmis:document") {
				$node['id'] = $obj->properties['cmis:objectId'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['cls'] = "document";
				$node['leaf'] = true;
				$node['text'] =  $obj->properties['cmis:name'];
        		} elseif (isset($obj->properties['cmis:baseTypeId']) && $obj->properties['cmis:baseTypeId'] == "cmis:folder") {
				$node['id'] = $obj->properties['cmis:path'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['cls'] = "folder";
				$node['leaf'] = false;
				$node['text'] =  $obj->properties['cmis:name'];
        		} else {
				$node['id'] = $obj->properties['cmis:objectId'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['cls'] = "document";
				$node['leaf'] = true;
				$node['text'] =  $obj->properties['cmis:name'];
        		}
			$nodes[] = $node;
		}
		echo json_encode($nodes);
	}
	
	public function actionCopyFile() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		$content = $this->actionGetObject();
		if (@$client->createDocument($_GET['dst'],$_GET['filename'],array(),$content, "text/xml")) {
                        echo '{
                                "success":true,
                                "msg":"File Created"
                        }';
                } else {
                        echo '{
                                "success":false,
                                "msg":"Creating File failed"
                        }';
                }
	}

	public function actionAddFile() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		
		$content = file_get_contents("protected/models/dita/" . strtolower($_POST['itemType']) . ".xml");
		$content = str_replace(array(
			"%id%",
			"<?xm-replace_text Title?>",
			"%product%",
			"%user%",
			"%datetime%"),
			array(md5(time()),
			$_POST['itemName'],
			"System Name",
			$this->repo_username,
			date("c")),
		$content);
		if (@$client->createDocument($_POST['cmisId'],$_POST['fileName'],array(),$content, "text/xml")) {
			echo '{
				"success":true,
				"msg":"File Created"
			}';
		} else {
			echo '{
				"success":false,
				"msg":"Creating file failed"
			}';	
		}
	}
	
	public function actionGetUsername() {
		echo $this->repo_username;
	}
	
	public function actionAddFolder() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		if (@$client->createFolder($_POST['cmisId'], $_POST['itemName'])) {
			echo '{
				"success":true,
				"msg":"Folder Created"
			}';
		} else {
			echo '{
				"success":false,
				"msg":"Creating folder failed"
			}';	
		}
		

		
	}
	
	public function actionDelete() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		$msg = $client->deleteObject($_POST['id']);
		if ($msg) {
			echo '{
				"success":true,
				"msg":"Item Deleted " 
			}';
		} else {
			echo '{
				"success":false,
				"msg":"Could not delete item"
			}';	
		}
	}

	public function actionGetAudiences() {
	        $s = simplexml_load_file("protected/data/conditions_default.xml");
        	$nodes = array();
        	foreach ($s->children() as $category) {
                	$node = array();
                	$group = $category['name'];
                	$node['id'] = (string)$group;
                	$node['xtype'] = 'checkboxgroup';
                	$node['fieldLabel'] = (string)$category['title'];
                	$node['columns'] = 1;
                	$node['width'] = 200;
                	foreach ($category->children() as $value) {
                        	$node['items'][] = array(
                                	'name'=>(string)$value['name'],
                                	'boxLabel'=>(string)$value['title'],
                                	'xtype'=>'checkbox'
                        	);
                	}	
                	$nodes[] = array('text'=>(string)$category['title'],'menu'=>array($node));
        	}
		echo json_encode($nodes);
	}
	
	public function actionGetObject() {
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		$id = $_GET['id'];
		$data = $client->getContentStream($id);
		return $data;
	}

	public function actionGetImage()
	{
		$data = $this->actionGetObject();
		echo $data;
	}
	public function actionShow()
	{
		echo $this->actionGetObject();
		//$this->render('show');
	}

	public function actionShowHtml()
	{
		$xml = $this->actionGetObject();
		$content = doTransform($xml, 'DITA-OT/plugins/ditaserver/clipboard.xsl',isset($_GET['filter'])?$_GET['filter']:array());
		echo $content;
	}

        /**
         * Browse ditamaps for EXTJS TreePanel
         *
         * @return void
         * @author Alex
         **/
        public function actionGetMapNodes() {
                global $mapRoot;
                $title = false;
                if (preg_match("/(.*)~(.*)/",$_REQUEST['node'],$regs)) {
                         $mapCmisId = $regs[1];
                         $resourceName = $regs[2];
                } else {
                        $mapCmisId = $_REQUEST['node'];
                }
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
		$mapPayload = $client->getContentStream($mapCmisId);
                $domXml = new DomDocument();
                $domXml->resolveExternals = true;
                $domXml->loadXml($mapPayload);

                $s = simplexml_import_dom($domXml);
                if (!isset($resourceName)) {//we've for root
                        $contextNode = $s;
                        $title = $s->xpath('//*[contains(@class, " map/map ")][1]/@title');
                        if (empty($title)) {
                                $title = $s->xpath('//*[contains(@class, " map/map ")][1]/*[contains(@class, " topic/title ")]/text()');
                        }

                        $node['id'] = $mapCmisId . "~";
                        $node['text'] = (string)$title[0];
                        $node['objectId'] = $mapCmisId;
                        $node['leaf'] =  false;
                        $node['cls'] = 'document';
                        $nodes[] = $node;
                } else {//we've got sub
                        if (!empty($regs[2])) {
                                if (preg_match("/^navtitle/",$regs[2])) {//dealing with navtitle
                                        $contextNode = $s->xpath("//*[contains(@navtitle,'" . str_replace("navtitle","",$resourceName) . "')]");
                                } else {
                                        $contextNode = $s->xpath("//*[contains(@href,'" . $resourceName . "')]");
                                }
                                $contextNode = $contextNode[0];
                        } else {
                                $contextNode = $s;
                        }
                        foreach ($contextNode->children() as $key1=>$val1) {
                                $node = array();
                                switch (true) {
                                        case preg_match("/ topic\/title /",$val1['class'])://topichead

                                                /*$node['text'] = (string)$val1;
                                                $node['leaf'] =  false;
                                                $node['cls'] = 'folder';
                                                */
                                        break;
                                        case preg_match("/ mapgroup-d\/topichead /",$val1['class'])://topichead
                                                $node['id'] = $mapCmisId . "~navtitle" . (string)$val1['navtitle'];
                                                $node['text'] = (string)$val1['navtitle'];
                                                $node['leaf'] =  false;
                                                $node['cls'] = 'folder';
                                        break;
                                        case preg_match("/ map\/topicref /",$val1['class']) and preg_match("/\.ditamap/",$val1['href'])://topicref to map
                                                $id = $this->actionGetCmisId((string)$val1['href']);
						$content = $client->getContentStream($id);
                                                $domXml2 = new DomDocument();
                                                $domXml2->resolveExternals = true;
                                                $domXml2->loadXml($content);

                                                $doc = simplexml_import_dom($domXml2);
                                                $title = $doc->xpath('//*[contains(@class, " map/map ")][1]/*[contains(@class, " topic/title ")][1]/text()');
                                                if (empty($title)) {
                                                        $title = $doc->xpath('//*[contains(@class, " map/map ")][1]/@title');
                                                }
                                                $node['id'] = "/s/workspace:SpacesStore/i/" . $id . "/children";
                                                $node['text'] = $title;
                                                $node['objectId'] =  "/s/workspace:SpacesStore/i/" . $id;
                                                $node['leaf'] =  ($nodeType == "document")?true:false;
                                                $node['cls'] = 'folder';
                                                $mapFile = $mapRoot . '/' . $val1['href'];
                                                $map = loadXML($mapFile);
                                                $s2 = simplexml_import_dom($map);
                                        break;
                                        case preg_match("/ map\/topicref /",$val1['class']) and preg_match("/\.xml/",$val1['href'])://topicref to topic
                                                $id = $this->actionGetCmisId((string)$val1['href']);
						$content = $client->getContentStream($id);
                                                $domXml2 = new DomDocument();
                                                $domXml2->resolveExternals = true;
                                                $domXml2->loadXml($content);

                                                $doc = simplexml_import_dom($domXml2);
                                                $title = $doc->xpath('//*[contains(@class, " topic/topic ")][1]/*[contains(@class, " topic/title ")][1]/text()');
                                                $node['id'] = $mapCmisId . "~" . $val1['href'];
                                                $node['text'] = (isset($val1['navtitle'])?(string)$val1['navtitle']:(string)$title[0]);//$id;//;(string)$title[0];
                                                $node['objectId'] =  $id;
                                                $node['leaf'] =  false;
                                                $node['cls'] = 'document';
                                        break;
                                }
                                if (!empty($node)) {
                                $nodes[] = $node;
                                }

                        }
                }
                echo json_encode($nodes);
                exit;
        }

		

		public function actionSave() {
			global $HTTP_RAW_POST_DATA;
            $content = $HTTP_RAW_POST_DATA;
            $putData = tmpfile();
            fwrite($putData, $content);
            fseek($putData, 0);

            header('OK', true, 201);
            $client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
			$client->setContentStream($_GET['id'], $content,"application/atom+xml");
			
			echo "Ok";
		}
	public function actionBrowse() 
	{
		
		$this->repo_folder = urlencode(isset($_GET['node'])?$_GET['node']: $this->repo_folder);
		$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);

		$myfolder=$client->getObjectByPath($this->repo_folder);

		$objs=$client->getChildren($myfolder->id);
		$blackList = array(); //array of folders to ignore

		$out = "";
		foreach ($objs->objectList as $obj) {
			if (in_array($obj->properties['cmis:name'], $blackList)) continue;
        		if ($obj->properties['cmis:baseTypeId'] == "cmis:document") {
				$node['id'] = $obj->properties['cmis:objectId'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['cls'] = "document";
				$node['leaf'] = true;
				$node['text'] =  $obj->properties['cmis:name'];
        		} elseif ($obj->properties['cmis:baseTypeId'] == "cmis:folder") {
				$node['id'] = $obj->properties['cmis:path'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['cls'] = "folder";
				$node['leaf'] = false;
				$node['text'] =  $obj->properties['cmis:name'];
        		} else {
				$node['id'] = $obj->properties['cmis:path'];
				$node['objectId'] = $obj->properties['cmis:objectId'];
				$node['type'] = "unknown";
				$node['leaf'] = true;
				$node['text'] =  $obj->properties['cmis:name'];
        		}
			$nodes[] = $node;
		}
		echo json_encode($nodes);
	}
	
	public function actionLookup() {
		$_GET['context'] =  "lookup";
		$this->render('index');
	}
	
	public function actionShowXmetal() {
		echo "<html><head><title>XMetaL</title><style type='text/css'>body {margin:0px;padding:0px;}</style></head><body><iframe id='xmetal' width='100%' height='100%' src='?r=site/login' border='0' style='border:0px'></iframe></body></html>";
	}

	public function actionShowXopus() {
		  $id = $_REQUEST['id'];
		
		  if (array_key_exists('fileType', $_REQUEST)) {
		    $fileType = $_REQUEST['fileType'];
		  }
		  if (!isset($fileType)) {
		    $doc = new DOMDocument;
			$client=new CMISService($this->repo_url,$this->repo_username,$this->repo_password);
			$payload = $client->getContentStream($id);
		    $doc->loadXML($payload);
		    $fileType = $doc->documentElement->localName;
		  }
		  if ($fileType == "dita") {
		    $fileType = "ditabase";
		  }

		  $config = new DOMDocument;
		  $config->load("xopus/dita/xsd/catalog.xml");
		  $xpath = new DOMXPath($config);
		  $xpath->registerNamespace("a", "urn:oasis:names:tc:entity:xmlns:xml:catalog");
		  $schema = 'xopus/dita/xsd/technicalContent/xsd/ditabase.xsd';
		  $system = $xpath->evaluate("a:system[@uri = '$fileType.xsd']", $config->documentElement)->item(0);
		  if ($system) {
		    $schema = 'xopus/dita/xsd/' . $system->getAttribute("xml:base") . $system->getAttribute("uri");
		  }
		

		  $docstring = "<?xml version='1.0' ?>
		  <island>
		    <canvas>
		      <fileType>$fileType</fileType>
		      <fileId>?r=cmis/show&amp;id=" . $id . "</fileId>
		      <schema>$schema</schema>
		    </canvas>
		  </island>";

		  $doc = new DOMDocument;
		  $doc->loadXML($docstring);
		  $tpl = new DOMDocument;
		  $tpl->load("xopus/dita/example-app/view-xopus-island.xsl");
		  $xsltproc = new XSLTProcessor;
		  $xsltproc->importStylesheet($tpl);
		  echo $xsltproc->transformToXML($doc);

	}

	// -----------------------------------------------------------
	// Uncomment the following methods and override them if needed
	/*
	public function filters()
	{
		// return the filter configuration for this controller, e.g.:
		return array(
			'inlineFilterName',
			array(
				'class'=>'path.to.FilterClass',
				'propertyName'=>'propertyValue',
			),
		);
	}

	public function actions()
	{
		// return external action classes, e.g.:
		return array(
			'action1'=>'path.to.ActionClass',
			'action2'=>array(
				'class'=>'path.to.AnotherActionClass',
				'propertyName'=>'propertyValue',
			),
		);
	}
	*/
        /**
         * Yii Filter method used to control caching and access
         *
         * @return void
         * @author Alex
         **/
        public function filters() {
                // return the filter configuration for this controller, e.g.:
                return array(
                array(
                        'COutputCache',
                        'duration'=>100,
                        'varyByParam'=>array('path'),
                        ),

                        'accessControl - login'
                        );
        }

        /**
         * Yii method for controlling access to methods
         *
         * @return array
         * @author Alex
         **/
        public function accessRules() {
                return array
                (
                array(
                        'allow',
                        'actions'=>array('showHtml','getAudiences','getCmisId','getDocument','copyFile','showXmetal'),
                        'users'=>array("*")),
                        array
                        ('allow',
                        'actions'=>array('getusername','show','showXopus','getObject','save','testCmis','getImage','search','browse','addFile','addFolder','delete','lookup','getCmisNodes','getMapNodes','index'),
                        'users'=>array('@')
                        ),
                        array
                        ('deny',
                        'users'=>array('*')
                        )
                        );
        }
}
